package com.chinapost.service.impl;

import java.io.File;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.chinapost.dao.BaseDaoI;
import com.chinapost.excelUtil.ExcelUtil;
import com.chinapost.po.Tdept;
import com.chinapost.po.Tresource;
import com.chinapost.po.Trole;
import com.chinapost.po.Tuser;
import com.chinapost.po.Tyglb;
import com.chinapost.service.UserServiceI;
import com.chinapost.util.Encrypt;
import com.chinapost.vo.DataGrid;
import com.chinapost.vo.User;

@Service("userService")
public class UserServiceImpl implements UserServiceI {

	@Autowired
	private BaseDaoI<Tuser> userDao;
	@Autowired
	private BaseDaoI<Tdept> deptDao;
	@Autowired
	private BaseDaoI<Trole> roleDao;
	@Autowired
	private BaseDaoI<Tyglb> yglbDao;


	@Override
	public void add(User user) {
		Tuser t = new Tuser();
		Date d = new Date();
		BeanUtils.copyProperties(user, t);
		t.setCid(UUID.randomUUID().toString());
		t.setCpwd(Encrypt.e(user.getCpwd().trim()));
		t.setCcreatedate(new Timestamp(d.getTime()));
		t.setCmodifydate(new Timestamp(d.getTime()));
		t.setTdept(deptDao.get(Tdept.class, user.getDeptid()));
		t.setTyglb(yglbDao.get(Tyglb.class, user.getYglbid()));
		t.setCstate(0);
		t.setClogin(0);
		if (user.getRoleIds().contains("9999")){
			t.setCkind(2);//普通用户设为2，用来统计积分
		}else{
			t.setCkind(1);//其他用户设为1，不统计积分
		}
		userDao.save(t);
		this.saveUserRole(user, t);
	}

	private void saveUserRole(User user, Tuser u) {
		if (user.getRoleIds() != null) {
			u.setTroles(new HashSet<Trole>());
			for (String id : user.getRoleIds().split(",")) {
				if (!StringUtils.isBlank(id)) {
					Trole trole = roleDao.get(Trole.class, id.trim());
					if (trole != null) {
						u.getTroles().add(trole);
					}
				}
			}
		}
	}

	@Override
	public void edit(User user) {
		Tuser t = userDao.get(Tuser.class, user.getCid());
		BeanUtils.copyProperties(user, t, new String[] { "ccreatedate", "cid", "cpwd", "clogin", "cstate", "ckind","clastlogin" });
		Date d = new Date();
		t.setCmodifydate(new Timestamp(d.getTime()));
		if (user.getCpwd() != null && !user.getCpwd().isEmpty()) {
			t.setCpwd(Encrypt.e(user.getCpwd()));
		}
		t.setTdept(deptDao.get(Tdept.class, user.getDeptid()));
		if (user.getYglbid()!=null){
			t.setTyglb(yglbDao.get(Tyglb.class, user.getYglbid()));
		}
		this.saveUserRole(user, t);
	}

	@Override
	public void delete(User user) {
		String cids = "";
		if (user.getIds() != null) {
			String ids = user.getIds();
			for (String cid : ids.split(",")) {
				cids += "'" + cid + "'" + ",";
			}
			cids = cids.substring(0, cids.length() - 1);
			String hql = "delete Tuser t where t.cid in (" + cids + ")";
			userDao.executeHql(hql);
		}

	}

	@Override
	public User login(User user) {
		Map<String, Object> m = new HashMap<String, Object>();
		User u = new User();
		List<Tuser> tuserList = null;
		String hql = " from Tuser t where  t.cbh= :name ";
		m.put("name", user.getCname());
		tuserList = userDao.find(hql, m);
		if (tuserList == null || tuserList.size() == 0) {
			u.setError(1);
			u.setSuccess(false);
			return u;
		}
		hql += " and t.cpwd = :password";
		m.put("password", Encrypt.e(user.getCpwd()));
		tuserList = userDao.find(hql, m);
		if (tuserList == null || tuserList.size() == 0) {
			u.setError(2);
			u.setSuccess(false);
			return u;
		}
		hql += " and t.cstate =1";
		Tuser t = userDao.get(hql, m);
		if (t == null ) {
			u.setError(3);
			u.setSuccess(false);
			return u;
		} else {
			t.setClogin(t.getClogin() + 1);
			t.setClastlogin(new Timestamp((new Date()).getTime()));
			BeanUtils.copyProperties(t, u, new String[] { "cpwd" });
			u.setDeptid(t.getTdept().getCid());
			u.setDeptname(t.getTdept().getCname());
			u.setSuccess(true);
			u = setRoleResource(t, u);
			return u;
		}
	}

	private User setRoleResource(Tuser t, User user) {
		// 获取用户所有角色
		String roleIds = "";
		String roleNames = "";
		String resourceUrls = "";
		Boolean b1 = false;
		Set<Trole> troles = t.getTroles();
		Set<Tresource> tresources = new HashSet<Tresource>();
		if (troles != null && troles.size() > 0) {
			for (Trole trole : troles) {
				if (b1) {
					roleIds += ",";
					roleNames += ",";
				}
				roleIds += trole.getCid();
				roleNames += trole.getCname();
				// 添加用户的所有可访问资源合集
				tresources.addAll(trole.getTresources());
				b1 = true;
			}
		}
		user.setRoleIds(roleIds);
		user.setRoleNames(roleNames);
		List<Tresource> list = new ArrayList<Tresource>(tresources);
		Boolean b2 = false;
		for (Tresource resource : list) {
			if (b2) {
				resourceUrls += ",";
			}
			resourceUrls += resource.getCurl();
			b2 = true;
		}
		user.setResourceUrls(resourceUrls);
		return user;
	}

	@Override
	public boolean changePwd(User user) {
		boolean b = false;
		if (user != null && user.getCid() != null && user.getCpwd() != null && user.getNewpwd() != null) {
			Tuser t = userDao.get(Tuser.class, user.getCid());
			if (t.getCpwd().equals(Encrypt.e(user.getCpwd()))) {
				t.setCpwd(Encrypt.e(user.getNewpwd()));
				Date d = new Date();
				t.setCmodifydate(new Timestamp(d.getTime()));
				b = true;
			}
		}
		return b;
	}

	@Override
	public DataGrid datagrid(User user) {
		DataGrid dg = new DataGrid();
		dg.setRows(listRows(find(user)));
		dg.setTotal(total(user));
		return dg;
	}

	private Long total(User user) {
		String hql = "select count(*) from Tuser t where 1=1";
		Map<String, Object> params = new HashMap<String, Object>();
		hql = addWhere(user, hql, params);
		return userDao.count(hql, params);
	}

	private List<Tuser> find(User user) {
		String hql = "from Tuser t where 1=1";
		Map<String, Object> params = new HashMap<String, Object>();
		hql = addWhere(user, hql, params);
		if (user.getOrder() != null && user.getSort() != null) {
			hql += " order by " + user.getSort() + " " + user.getOrder();
		}
		return userDao.find(hql, params, user.getPage(), user.getRows());
	}

	private List<User> listRows(List<Tuser> lt) {
		List<User> rows = new ArrayList<User>();
		if (lt != null && lt.size() > 0) {
			for (Tuser t : lt) {
				User sub = new User();
				BeanUtils.copyProperties(t, sub, new String[] { "cpwd" });
				sub.setDeptid(t.getTdept().getCid());
				sub.setDeptname(t.getTdept().getCname());
				Set<Trole> troles = t.getTroles();
				String roleIds = "";
				String roleNames = "";
				boolean b = false;
				if (troles != null && troles.size() > 0) {
					for (Trole trole : troles) {
						if (b) {
							roleIds += ",";
							roleNames += ",";
						}
						roleIds += trole.getCid();
						roleNames += trole.getCname();
						b = true;
					}
				}
				if (t.getTyglb()!=null){
					sub.setYglbid(t.getTyglb().getCid());
					sub.setYglbname(t.getTyglb().getCname());
				}
				sub.setRoleIds(roleIds);
				sub.setRoleNames(roleNames);
				rows.add(sub);
			}
		}
		return rows;
	}

	private String addWhere(User user, String hql, Map<String, Object> params) {
		if (user != null && user.getCid() != null && !user.getCid().trim().equals("")) {
			hql += " and t.cid = :id ";
			params.put("id", user.getCid());
		}
		if (user != null && user.getCbh() != null && !user.getCbh().trim().equals("")) {
			hql += " and t.cbh = :bh ";
			params.put("bh", user.getCbh());
		}
		if (user != null && user.getDeptIds() != null && user.getDeptIds().size() > 0) {
			hql += " and t.tdept.cid in (:deptids)";
			params.put("deptids", user.getDeptIds());
		}
		if (user != null && user.getCname() != null && !user.getCname().trim().equals("")) {
			hql += " and t.cname like :username ";
			params.put("username", "%%" + user.getCname() + "%%");
		}
		return hql;
	}

	@Override
	public void changeStatus(User user) {
		if (user != null && user.getCid() != null) {
			Tuser t = userDao.get(Tuser.class, user.getCid());
			if (t.getCstate() == 1) {
				t.setCstate(0);
			} else {
				t.setCstate(1);
			}
			Date d = new Date();
			t.setCmodifydate(new Timestamp(d.getTime()));
		}
	}

	@Override
	public Integer addUsers(User user) {
		int i = 0;
		// String[] fields = { "cdept", "cbh", "cname" };
		if (user != null && !StringUtils.isEmpty(user.getDeptid()) && !StringUtils.isEmpty(user.getFilename())) {
			ExcelUtil eu = new ExcelUtil();
			List<ArrayList<String>> userList = eu.read(user.getFilename(), 2);// 从第三行开始读取
			String hql = " from Tdept t where t.tdept.cid = :deptid and t.cname =:deptname";
			Map<String, Object> params = new HashMap<String, Object>();
			String hql_user = " from Tuser t where t.cbh =:bh";
			Map<String, Object> params_user = new HashMap<String, Object>();
			params.put("deptid", user.getDeptid());
			Trole role = roleDao.get(Trole.class, "9999");
			for (ArrayList<String> row : userList) {
				String deptname = row.get(0).trim();
				String userbh = row.get(1).trim();
				String username = row.get(2).trim();
				Integer yglb = Integer.parseInt(row.get(3).trim());
				if (!StringUtils.isEmpty(deptname) && !StringUtils.isEmpty(username) && !StringUtils.isEmpty(userbh)) {
					params.put("deptname", deptname);
					Tdept tdept = deptDao.get(hql, params);
					if (tdept != null) {
						params_user.put("bh", userbh);
						Tuser tuser = userDao.get(hql_user, params_user);
						if (tuser == null) {
							Tuser t = new Tuser();
							t.setCid(UUID.randomUUID().toString());
							t.setTdept(tdept);
							t.setCbh(userbh);
							t.setCpwd(Encrypt.e("123"));
							t.setCname(username);
							t.setClogin(0);
							t.setTyglb(yglbDao.get(Tyglb.class, yglb));
							t.getTroles().add(role);
							t.setCkind(2);
							Date d = new Date();
							t.setCcreatedate(new Timestamp(d.getTime()));
							t.setCmodifydate(new Timestamp(d.getTime()));
							t.setCstate(0);
							userDao.save(t);
							i++;
						}
					}
				}
			}
			File f = new File(user.getFilename());
			if (f.exists() && f.isFile()) {
				f.delete();
			}
		}
		return i;
	}

	@Override
	public List<User> listUserByDeptid(String deptid) {
		List<User> users = new ArrayList<User>();
		String hql = " from Tuser t where t.tdept.cid = :deptid";
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("deptid", deptid);
		List<Tuser> tusers = userDao.find(hql, params);
		if (tusers != null && tusers.size()>0){
			for (Tuser tuser : tusers){
				User u = new User();
				u.setCbh(tuser.getCbh());
				u.setCname(tuser.getCname()+"("+tuser.getCbh()+")");
				users.add(u);
			}
		}
		return users;
	}

	@Override
	public String getNameByBh(String bh) {
		String hql = " from Tuser t where t.cbh =:bh";
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("bh", bh);
		Tuser tuser = userDao.get(hql, params);
		if (tuser != null){
			return tuser.getCname();
		}
		return null;
	}

	@Override
	public List<User> excelData(User user) {
		String hql = "from Tuser t where 1=1 ";
		Map<String, Object> params = new HashMap<String, Object>();
		hql = addWhere(user, hql, params);
		hql += " and t.ckind=2  order by t.tdept.cseq,t.cbh";
		List<Tuser> users = userDao.find(hql, params);
		return listRows(users);
	}

}
